/**
 * 
 * Copyright (C) 2011 Cody Stoutenburg . All rights reserved.
 *
 *       This program is free software; you can redistribute it and/or
 *       modify it under the terms of the GNU Lesser General Public License
 *       as published by the Free Software Foundation; either version 2.1
 *       of the License, or (at your option) any later version.
 *
 *       This program is distributed in the hope that it will be useful,
 *       but WITHOUT ANY WARRANTY; without even the implied warranty of
 *       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *       GNU Lesser General Public License for more details.
 *
 *       You should have received a copy of the GNU Lesser General Public License
 *       along with this program; if not, write to the Free Software
 *       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
 * 
 */
package net.alteiar.plateform.game;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.alteiar.plateform.game.model.Entity;

/**
 * @author Cody Stoutenburg
 * 
 */
public class World {

	private final Long realWidth;
	private final Long realHeight;

	private final Map<Long, Entity> allCharacter;

	private final List<WorldObserver> observers;

	/**
	 * @param realWidth
	 * @param realHeight
	 */
	public World(Long widthInMeter, Long heightInMeter) {
		super();
		this.realWidth = widthInMeter;
		this.realHeight = heightInMeter;

		allCharacter = new HashMap<Long, Entity>();
		observers = new ArrayList<WorldObserver>();
	}

	public Collection<Entity> getAllCharacters() {
		return allCharacter.values();
	}

	public Long getWidth() {
		return this.realWidth;
	}

	public Long getHeight() {
		return this.realHeight;
	}

	public void addEntity(Entity element) {
		this.allCharacter.put(element.getGuid(), element);
		notifyEntityAdded(element);
	}

	public void update(long timeMs) {
		List<Entity> allCharacter = new ArrayList<Entity>(getAllCharacters());
		for (Entity element : allCharacter) {
			element.doLogic();
			element.move(timeMs);
		}

		for (int i = 0; i < allCharacter.size(); ++i) {
			Entity character = allCharacter.get(i);
			for (int j = i + 1; j < allCharacter.size(); ++j) {
				if (character.checkCollisionWith(allCharacter.get(j))) {
					character.collidedWith(allCharacter.get(j));
					allCharacter.get(j).collidedWith(character);
				}
			}
		}
	}

	/*
	 * Observers method
	 */
	public void addObserver(WorldObserver obs) {
		this.observers.add(obs);
	}

	/**
	 * 
	 * @param entity
	 */
	protected void notifyEntityAdded(Entity entity) {

		for (WorldObserver observer : observers) {
			observer.entitieAdded(entity);
		}
	}
}
